package com.biostime.qdingding.modules.qd.web;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.biostime.qdingding.common.config.Global;
import com.biostime.qdingding.common.utils.DateUtils;
import com.biostime.qdingding.common.utils.FileUtils;
import com.biostime.qdingding.common.utils.ImageUtils;
import com.biostime.qdingding.common.utils.StringUtils;
import com.biostime.qdingding.common.web.BaseController;
import com.google.common.collect.Lists;

/**
 * 上传Controller
 * @author phil
 * @version 2015-11-17
 */
@Controller
@RequestMapping(value = "${adminPath}/qd/upload")
public class UploadController extends BaseController {
	
	@ResponseBody()
	@RequestMapping(value = {""},produces="application/json;charset=utf-8")
	public String processRequest(HttpServletRequest request, HttpServletResponse response){
		String action = request.getParameter("action");
		String msg = "";
		switch(action){
			case "EditorFile": //编辑器文件
				msg = editorFile(request,response);
	            break;
	        case "ManagerFile": //管理文件
	        	msg = managerFile(request,response);
	            break;
	        default: //普通上传
	        	msg = upLoadFile(request,response);
	            break;
		}
		
		return msg;
	}

	private String upLoadFile(HttpServletRequest request,
			HttpServletResponse response) {
		try{
			//检查输入请求是否为multipart表单数据。
			boolean isMultipart = ServletFileUpload.isMultipartContent(request);
			String msg = "";
			
			if(!isMultipart){
				msg = "{\"status\": 0, \"msg\": \"form标签enctype必须为multipart/form-data！\"}";
			}
			
			boolean _iswater = false; //默认不打水印
			boolean _isthumbnail = false; //默认不生成缩略图
			
			String type = request.getParameter("Type");
			if(StringUtils.isEmpty(type)){
				msg = "{\"status\": 0, \"msg\": \"请设置上传分类(type参数为空)！\"}";
				return msg;
			}
	        
			if(StringUtils.toInteger(request.getParameter("IsWater")) == 1){
				_iswater = true;
			}
			
			if(StringUtils.toInteger(request.getParameter("IsThumbnail")) == 1){
				_isthumbnail = true;
			}
			
			DiskFileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload= new ServletFileUpload(factory);
			
			@SuppressWarnings("unchecked")
			List<FileItem> items = upload.parseRequest(request) ; // 接收全部内容
			
			if(items.size()<=0){
				msg = "{\"status\": 0, \"msg\": \"请选择要上传文件！\"}";
				return msg;
			}
			
			FileItem _upfile = null;
			
			for(FileItem item : items){
				if(item.getFieldName().equals("Filedata")){
					_upfile = item;
				}
			}
			
			UpLoad upFiles = new UpLoad();
            msg = upFiles.fileSaveAs(type, _upfile, _isthumbnail, _iswater);
            
            //返回成功信息
            return msg;
		}catch(Exception ex){
			ex.printStackTrace();
			return "{\"status\": 0, \"msg\": \"上传文件出现异常！\"}";
		}
	}

	private String managerFile(HttpServletRequest request,
			HttpServletResponse response) {
		return "";
	}

	private String editorFile(HttpServletRequest request,
			HttpServletResponse response) {
		return "";
	}
	
	public static class UpLoad{
		
		/**
		 * 保存上传图片
		 * @param type
		 * @param upfile
		 * @param isthumbnail
		 * @param iswater
		 * @return
		 */
		public String fileSaveAs(String type, FileItem upfile, boolean isthumbnail, boolean iswater) {
			try{
				String fileExt = getFileExt(upfile.getName()); //文件扩展名，不含“.”
				
				int imgmaxwidth = StringUtils.toInteger(Global.getConfig("upload.imgmaxwidth")); //上传图片最大宽度
				int imgmaxheight = StringUtils.toInteger(Global.getConfig("upload.imgmaxheight")); //上传图片最大高度
				
				int thumbnailwidth = StringUtils.toInteger(Global.getConfig("upload.thumbnailwidth")); //上传图片默认生成缩略图宽度
				int thumbnailheight = StringUtils.toInteger(Global.getConfig("upload.thumbnailheight")); //上传图片默认生成缩略图高度
				
				long fileSize = upfile.getSize(); //获得文件大小，以字节为单位
				String fileName = upfile.getName().substring(upfile.getName().lastIndexOf("/") + 1); //取得原文件名
				
				String ramFileName = getRamCode();
				
				String newFileName = ramFileName + "." + fileExt; //随机生成新的文件名
				String newThumbnailFileName = String.format("%s_%sx%s", ramFileName, thumbnailwidth, thumbnailheight) + "." + fileExt; //随机生成缩略图文件名
				String upLoadPath = getUpLoadPath(type); //上传目录相对路径
				
				String newFilePath = upLoadPath + newFileName; //上传后的路径
	            String newThumbnailPath = upLoadPath + newThumbnailFileName; //上传后的缩略图路径
				
	            //检查文件扩展名是否合法
	            if (!checkFileExt(fileExt))
	            {
	                return "{\"status\": 0, \"msg\": \"不允许上传" + fileExt + "类型的文件！\"}";
	            }
				
	            //检查文件大小是否合法
	            if (!checkFileSize(fileExt, fileSize))
	            {
	                return "{\"status\": 0, \"msg\": \"文件超过限制的大小！\"}";
	            }
	    		
	            //检查上传的物理路径是否存在，不存在则创建
	            String fullUpLoadPath = Global.getUserfilesBaseDir();
	            if(!fullUpLoadPath.endsWith("/")){
	            	fullUpLoadPath += "/";
	            }
	            
	            fullUpLoadPath += Global.USERFILES_BASE_URL + upLoadPath;
	            
				FileUtils.createDirectory(FileUtils.path(fullUpLoadPath));
				
				FileUtils.createFile(fullUpLoadPath + newFileName);
				Streams.copy(upfile.getInputStream(), new FileOutputStream(fullUpLoadPath + newFileName), true, new byte[1024]);
				
				//如果是图片，检查图片是否超出最大尺寸，是则裁剪
                if (isImage(fileExt) && (imgmaxheight > 0 || imgmaxwidth > 0))
                {
                	ImageUtils.scale(new File(fullUpLoadPath + newFileName), new File(fullUpLoadPath + newFileName), imgmaxwidth, imgmaxheight, 0, false, 0.8f);
                }
                
                //如果是图片，检查是否需要生成缩略图，是则生成
                if (isImage(fileExt) && isthumbnail && thumbnailwidth > 0 && thumbnailheight > 0)
                {
                	//ImageUtils.scale(new File(fullUpLoadPath + newFileName), new File(fullUpLoadPath + newThumbnailFileName), thumbnailwidth, thumbnailheight, 0, false, 0.8f);
                	ImageUtils.clipBySize(new File(fullUpLoadPath + newFileName), new File(fullUpLoadPath + newThumbnailFileName), thumbnailwidth, thumbnailheight, false, 0.8f);
                }
                else
                {
                    newThumbnailPath = newFilePath; //不生成缩略图则返回原图
                }
				
                //如果是图片，检查是否需要打水印
                if (isWaterMark(fileExt) && iswater)
                {
                    switch (Global.getConfig("watermarktype"))
                    {
                        case "1":
                            /*WaterMark.AddImageSignText(newFilePath, newFilePath,
                                this.siteConfig.watermarktext, this.siteConfig.watermarkposition,
                                this.siteConfig.watermarkimgquality, this.siteConfig.watermarkfont, this.siteConfig.watermarkfontsize);
                            */break;
                        case "2":
                            /*WaterMark.AddImageSignPic(newFilePath, newFilePath,
                                this.siteConfig.watermarkpic, this.siteConfig.watermarkposition,
                                this.siteConfig.watermarkimgquality, this.siteConfig.watermarktransparency);
                            */break;
                    }
                }
                
                if(isImage(fileExt)){
                	/**处理Path**/
                    newFilePath = newFilePath.replaceFirst("/", "");
                    newFilePath = newFilePath.replace("/", "-");
                    newFilePath = newFilePath.replace(".", "-");
                    
                    newThumbnailPath = newFilePath + String.format("_%sx%s", thumbnailwidth, thumbnailheight);
                }else{
                	newThumbnailPath = "";
                }
                
				//处理完毕，返回JOSN格式的文件信息
                return "{\"status\": 1, \"msg\": \"上传文件成功！\",\"type\":\""+ type +"\", \"name\": \""
                    + fileName + "\", \"path\": \"" + newFilePath + "\", \"thumb\": \""
                    + newThumbnailPath + "\", \"size\": " + fileSize + ", \"ext\": \"" + fileExt + "\"}";
			}catch(Exception ex){
				ex.printStackTrace();
				return "{\"status\": 0, \"msg\": \"上传过程中发生意外错误！\"}";
			}
		}
		
		/**
		 * 判断文件是否支持水印
		 * @param fileExt 文件拓展名
		 * @return
		 */
		private boolean isWaterMark(String fileExt) {
			return false;
		}
		
		/**
		 * 检查文件上传大小
		 * @param fileExt
		 * @param fileSize
		 * @return
		 */
		private boolean checkFileSize(String fileExt, long fileSize) {
			
			int fs = StringUtils.toInteger(Global.getConfig("uplaod.filesize"));
			
			return fileSize < fs*1024*1024;
		}

		/**
		 * 检查文件合法性
		 * @param fileExt
		 * @return
		 */
		private boolean checkFileExt(String fileExt) {
			return true;
		}

		/**
		 * 获取上传目录
		 * @return
		 */
		private String getUpLoadPath(String type) {
			
			String path = "/" + type + "/"; //站点目录+上传目录
			Date now = new Date();
            switch (Global.getConfig("filesave"))
            {
                case "1": //按年月/日存入不同的文件夹
                	path += DateUtils.formatDate(now, "yyyyMM") + "/" + DateUtils.formatDate(now, "dd");
                    break;
                default: //按年月日每天一个文件夹
                	path += DateUtils.formatDate(now, "yyyyMMdd");
                    break;
            }
            return path + "/";
		}

		/**
		 * 获取上传文件随机名
		 * @return
		 */
		private String getRamCode() {
			int random = new Random().nextInt(10000);
			return new StringBuffer()
			.append(DateUtils.formatDate(new Date(), "yyyyMMddHHmm"))
			.append(String.format("%04d", random)).toString();
		}

		/**
		 * 获取文件拓展名
		 * @param filename
		 * @return
		 */
		private String getFileExt(String filename) {
			if(StringUtils.isEmpty(filename)){
				return "jpg";
			}
			
			return filename.substring(filename.lastIndexOf(".")+1);
		}

		/**
		 * 是否为图片文件
		 * @param _fileExt 文件扩展名，不含“.”
		 * @return
		 */
        private boolean isImage(String _fileExt)
        {
            List<String> al = Lists.newArrayList();
            al.add("bmp");
            al.add("jpeg");
            al.add("jpg");
            al.add("gif");
            al.add("png");
            if (al.contains(_fileExt.toLowerCase()))
            {
                return true;
            }
            return false;
        }
	}
}